package com.demo.spring.autowird;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;

public class Autowired底层演示8_Qualifier {
	
	public static void main(String[] args) throws Exception {
		GenericApplicationContext context = new GenericApplicationContext();
		context.registerBeanDefinition("service1", new AnnotatedGenericBeanDefinition(Service1.class));
		context.registerBeanDefinition("service2", new AnnotatedGenericBeanDefinition(Service2.class));
		context.registerBeanDefinition("target", new AnnotatedGenericBeanDefinition(Target.class));
		DependencyDescriptor dd1 = new DependencyDescriptor(Target.class.getDeclaredField("service"), true);
		Class<?> type = dd1.getDependencyType();
		String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context.getDefaultListableBeanFactory(), type);
		ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();
		resolver.setBeanFactory(context.getDefaultListableBeanFactory());
		for(String name : names) {
			System.out.println(name);
			// 找到BeanDefinition
			BeanDefinition bd = context.getDefaultListableBeanFactory().getMergedBeanDefinition(name);
			// 对比@Qualifier注解的name和BeanDefinitionHolder的name是否匹配
			// BeanDefinitionHolder就是比BeanDefinition多了bean name
			if(resolver.isAutowireCandidate(new BeanDefinitionHolder(bd, name), dd1)) {
				System.out.println("===:" + name);
				Object bean = context.getDefaultListableBeanFactory().getBean(name);
				System.out.println(bean);
			}
		}
	}
	
	static class Target {
		@Autowired
		@Qualifier("service2")
		private Service service;
	}
	
	static interface Service {
		
	}
	
	static class Service1 implements Service {
		
	}
	
	static class Service2 implements Service {
		
	}

}
